#include "remotehost.h"
#include <QBuffer>
#ifdef EREMOTEPROTOCOL_QDEBUG
#include <QDebug>
#endif
RemoteHost::RemoteHost(QObject *parent) : RemoteTcpSocket(parent)
{

}

RemoteHost::~RemoteHost()
{

}

bool RemoteHost::sendCreateWindow(int wid, int width, int height, int codec)
{
    int size = 0;
    Server2ClientMessageType mt = Server2ClientMessageType::S2C_CreateWindowEvent;
    size = sizeof(mt) +  sizeof(wid)+  sizeof(width)+  sizeof(height)+  sizeof(codec);
#ifdef EREMOTEPROTOCOL_QDEBUG
    qDebug()<<"发送CreateWindow数据包大小:"<<size;
#endif
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&size)), sizeof(size));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&mt)), sizeof(mt));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&wid)), sizeof(wid));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&width)), sizeof(width));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&height)), sizeof(height));
    return this->mustWrite(static_cast<const char*>(static_cast<const void *>(&codec)), sizeof(codec));
}

bool RemoteHost::sendWindowFramebuffer(int wid, const QByteArray &data)
{
    int size = 0;
    Server2ClientMessageType mt = Server2ClientMessageType::S2C_UpdateWindowFramebufferEvent;
    size = sizeof(mt) + sizeof(wid) + data.size();

#ifdef EREMOTEPROTOCOL_QDEBUG
    qDebug()<<"发送WindowFramebuffer数据包大小:"<<size;
#endif

    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&size)), sizeof(size));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&mt)), sizeof(mt));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&wid)), sizeof(wid));
    return this->mustWrite(data.data(), data.size());
}

bool RemoteHost::sendCutText(const QString &text)
{
    int size = 0;
    Server2ClientMessageType mt = Server2ClientMessageType::S2C_UpdateCutTextEvent;
    QByteArray utf8Buff = text.toUtf8();
    size = sizeof(mt) + utf8Buff.size();
#ifdef EREMOTEPROTOCOL_QDEBUG
    qDebug()<<"发送CutText数据包大小:"<<size;
#endif
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&size)), sizeof(size));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&mt)), sizeof(mt));
    return this->mustWrite(utf8Buff);
}

void RemoteHost::parsePacket(QByteArray &pkt)
{
    QBuffer bs(&pkt, this);
    if(!bs.open(QIODevice::ReadOnly))
    {
#ifdef EREMOTEPROTOCOL_QDEBUG
        qCritical()<<"打开数据流失败";
#endif
        return;
    }
    Client2ServerMessageType messageType;
    bs.read(static_cast<char*>(static_cast<void*>(&messageType)), sizeof(messageType));
    switch(messageType)
    {
    case C2S_KeyEvent:
    {
        int wid;
        int key = 0;
        bool isPress = true;
        bs.read(static_cast<char*>(static_cast<void*>(&wid)), sizeof(wid));
        bs.read(static_cast<char*>(static_cast<void*>(&key)), sizeof(key));
        bs.read(static_cast<char*>(static_cast<void*>(&isPress)), sizeof(isPress));
        emit this->receivedKey(wid, key, isPress);
    }
        break;
    case C2S_MouseEvent:
    {
        int wid;
        int key = 0;
        bool isPress = true;
        int x, y;
        bs.read(static_cast<char*>(static_cast<void*>(&wid)), sizeof(wid));
        bs.read(static_cast<char*>(static_cast<void*>(&key)), sizeof(key));
        bs.read(static_cast<char*>(static_cast<void*>(&isPress)), sizeof(isPress));
        bs.read(static_cast<char*>(static_cast<void*>(&x)), sizeof(x));
        bs.read(static_cast<char*>(static_cast<void*>(&y)), sizeof(y));

        emit this->receivedMouse(wid, key, isPress, x, y);
    }
        break;
    case C2S_WheelEvent:
    {
        int wid;
        int delta;
        bs.read(static_cast<char*>(static_cast<void*>(&wid)), sizeof(wid));
        bs.read(static_cast<char*>(static_cast<void*>(&delta)), sizeof(delta));
        emit this->receivedWheel(wid, delta);
    }
        break;
    case C2S_StartCap:
    {
        int wid;
        bs.read(static_cast<char*>(static_cast<void*>(&wid)), sizeof(wid));
        emit receivedStartCap();
    }
        break;
    case C2S_PauseCap:
    {
        int wid;
        bs.read(static_cast<char*>(static_cast<void*>(&wid)), sizeof(wid));
        emit receivedPauseCap();
    }
        break;
    case C2S_UpdateCutTextEvent:
    {
        emit this->receivedCutText(QString::fromUtf8(bs.readAll()));
    }
        break;
    default:
#ifdef EREMOTEPROTOCOL_QDEBUG
        qWarning()<<"未知的消息类型:"<<static_cast<uint16_t>(messageType);
#endif
        break;
    }
    if(!bs.atEnd())
    {
        qWarning()<<"Message("<<static_cast<int>(messageType)<<") message not read all";
    }
}
